package com.yanqu.road.server.gameplayer.module.newmonopolymkt;

import com.yanqu.road.dao.impl.nenmonopolymarket.NewMonopolyMarketReportDataDaoImpl;
import com.yanqu.road.dao.impl.nenmonopolymarket.NewMonopolyMarketUserDataDaoImpl;
import com.yanqu.road.entity.config.player.UserDecorationInfoResult;
import com.yanqu.road.entity.enums.eMonopolyMarketResType;
import com.yanqu.road.entity.enums.ePlayerAttrType;
import com.yanqu.road.entity.enums.eSkillType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.log.newmonopolymarket.NewMonopolyMarketUserPhysicalChangeLogData;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.player.UserInfo;
import com.yanqu.road.entity.systemgroup.common.SystemServerGroupWeekData;
import com.yanqu.road.entity.systemgroup.newmonopolymarket.NewMonopolyMarketUserData;
import com.yanqu.road.entity.systemgroup.newmonopolymarket.resgrab.NewMonopolyMarketReportData;
import com.yanqu.road.entity.systemgroup.newmonopolymarket.resgrab.NewMonopolyMarketResGrabDispatchInfo;
import com.yanqu.road.entity.systemgroup.newmonopolymarket.resgrab.NewMonopolyMarketTempPoint;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.pb.newmonopolymkt.NewMonopolyMarketProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.AttributeModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.gameplayer.module.player.DecorationModule;
import com.yanqu.road.server.gameplayer.module.player.PreReduceModule;
import com.yanqu.road.server.manger.activity.curio.CurioMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.systemgroup.CrossSystemGroupMgr;
import com.yanqu.road.server.manger.systemgroup.newmonopolymarket.NewMonopolyMarketMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.CrossProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;

import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class NewMonopolyMarketModule extends GeneralModule {

    public NewMonopolyMarketModule(GamePlayer player) {
        super(player);
    }

    public NewMonopolyMarketUserData userData;

    /**
     * 资源争夺战 预扣除体力
     */
    public int resGrabNeedPhysical;

    /**
     * 资源争夺战 预占领的等级
     */
    public int level;

    public List<NewMonopolyMarketReportData> officeReportList = new ArrayList<>();

    public List<NewMonopolyMarketReportData> resGrabReportList = new ArrayList<>();

    /**
     *  当前正在派遣的位置信息,结算完移除   k:资源分组id， k:位置id v：派遣的对象集合
     */
    private Map<Integer, Map<Integer, Set<NewMonopolyMarketResGrabDispatchInfo>>> curDispatchInfoListMap = new ConcurrentHashMap<>();

    /**
     * 所在的系统id (0表示在大厅 1榷署 2王帐 3王宫)
     */
    private int inSystemId = -1;

    //进入系统的时间
    public int inSystemTime = 0;

    @Override
    public boolean loadData() {
        if(SystemOpenMgr.systemOpen(player, eSystemId.NewMonopolyMarket.getValue())){
            userData = new NewMonopolyMarketUserDataDaoImpl().getNewMonopolyMarketUserData(player.getUserId());
            int weekId = GameConfig.getSystemThisWeekId();
            Map<Integer, List<NewMonopolyMarketReportData>> map = new NewMonopolyMarketReportDataDaoImpl().getNewMonopolyMarketReportData(player.getUserId(), weekId);
            for (Map.Entry<Integer, List<NewMonopolyMarketReportData>> entry : map.entrySet()) {
                List<NewMonopolyMarketReportData> list = entry.getValue();
                list.sort(Comparator.comparingInt(NewMonopolyMarketReportData::getTime));
                if(entry.getKey() == eMonopolyMarketResType.OFFICE_NEW.getValue()){
                    if(list.size() <= GameConfig.NEWMONOPOLYMARKET_KEEPINFO_1){
                        officeReportList.addAll(list);
                    }else {
                        officeReportList.addAll(list.subList(list.size() - GameConfig.NEWMONOPOLYMARKET_KEEPINFO_1, list.size()));
                    }
                }else {
                    if(list.size() <= GameConfig.NEWMONOPOLYMARKET_KEEPINFO_2){
                        resGrabReportList.addAll(list);
                    }else {
                        resGrabReportList.addAll(list.subList(list.size() - GameConfig.NEWMONOPOLYMARKET_KEEPINFO_2, list.size()));
                    }
                }
            }
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {

        if(userData != null){
            if (userData.isInsertOption()) {
                new NewMonopolyMarketUserDataDaoImpl().add(userData);
            } else if (userData.isUpdateOption()) {
                new NewMonopolyMarketUserDataDaoImpl().update(userData);
            }
        }
        // 更新榷署战报
        for(NewMonopolyMarketReportData reportData : officeReportList){
            if (reportData.isInsertOption()) {
                new NewMonopolyMarketReportDataDaoImpl().add(reportData);
            }else if(reportData.isUpdateOption()) {

            }
        }

        for(NewMonopolyMarketReportData reportData : resGrabReportList){
            if (reportData.isInsertOption()) {
                new NewMonopolyMarketReportDataDaoImpl().add(reportData);
            }else if(reportData.isUpdateOption()) {

            }
        }

        return true;
    }


    @Override
    public void afterLogin() {
        if(!NewMonopolyMarketMgr.canEnterSystem(player)){
            return;
        }
        initNewMonopolyMktUserData();
        getUserData();
        sendConfigToClient();
    }

    public void initSystem(){
        if(!NewMonopolyMarketMgr.canEnterSystem(player)){
            return;
        }
        initNewMonopolyMktUserData();
        getUserData();
        sendConfigToClient();
    }

    public synchronized void initNewMonopolyMktUserData(){
        if(userData != null){
            return;
        }
        NewMonopolyMarketUserData baseData = new NewMonopolyMarketUserData();
        baseData.setInsertOption();
        baseData.setUserId(player.getUserId());
        baseData.setWeekId(GameConfig.getSystemThisWeekId());
        baseData.setGuanYin(getInitGuanYin());
        baseData.setLastGuanYinRecTime(DateHelper.getCurrentSecond());
        //baseData.setTeaLastGetTime(DateHelper.getCurrentSecond());
        userData = baseData;
    }

    public int getInitGuanYin(){
        int addition = (int) CurioMgr.getSkillAdditionBySkillType(eSkillType.CurioNewMonopolyGuanYinSkill.getValue(), player, 0);
        //本周加成缓存
        player.getModule(AttributeModule.class).setAttribute(ePlayerAttrType.CurioMonopolyGuanYinAddition, addition);
        return GameConfig.NEWMONOPOLYMARKET_INITIAL_GUANYIN_MAX + addition;
    }

    /**
     * 每周重置
     */
    public void resetWeekUserData() {
        if(userData == null){
            return;
        }
        int weekId = GameConfig.getSystemThisWeekId();
        SystemServerGroupWeekData weekData = CrossSystemGroupMgr.getSystemServerGroup(weekId, eSystemId.NewMonopolyMarket.getValue());
        if(weekData == null){
            return;
        }
        synchronized (this) {
            if (userData.getWeekId() != weekId) {

                Calendar calendar = Calendar.getInstance();
                int day = calendar.get(Calendar.DAY_OF_WEEK);
                //六、日才重置玩家数据
                if(day != Calendar.SUNDAY && day != Calendar.SATURDAY){
                    return;
                }

                int oldValue = userData.getGuanYin();

                userData.setWeekId(weekId);
                //跨周重新刷一次
                userData.setGuanYin(getInitGuanYin());
                userData.setLastGuanYinRecTime(DateHelper.getCurrentSecond());
                userData.setGetUserReward(false);
                userData.setGetServerReward(false);
                userData.setHasTip(false);
                userData.getSearchPointMap().clear();
                userData.setWaitDispatchPoint(null);
                userData.setOfficeTip(null);
                userData.setActiveTime(0);
                userData.setTeaLastGetTime(0);

                AutoLogMgr.add(new NewMonopolyMarketUserPhysicalChangeLogData(getUserId(), userData.getWeekId(), userData.getOfficeCurPos(), userData.getOfficeLevel(),
                        userData.getOfficeNo(), 0, oldValue, userData.getGuanYin()));

            }
            if(weekData.getWeekId() == weekId && userData.getSystemGroupId() != weekData.getGroupId()){
                userData.setSystemGroupId(weekData.getGroupId());
            }
        }
    }

    /**
     *  找跨服同步玩家（返回榷署位置、资源点派遣信息、）
     *  (玩家登录、系统解锁、轮询开启、跨发资源点每日重置、跨服榷署周日22点结算)
     *  榷场数据
     */
    public void getUserData(){
        if (!NewMonopolyMarketMgr.canEnterSystem(player) || userData == null) {
            return;
        }
        NewMonopolyMarketProto.NewMonopolyMarketCheckUserDataToCrossReqMsg.Builder req = NewMonopolyMarketProto.NewMonopolyMarketCheckUserDataToCrossReqMsg.newBuilder();
        UserBaseInfo baseInfo = UserMgr.getUserBaseInfo(player.getUserId(), GameServer.getInstance().getServerId());
        if(baseInfo == null){
            return;
        }
        req.setPlayerInfo(PlayerBasePb.parsePlayerBaseTempMsg(baseInfo));
        UserDecorationInfoResult result = player.getModule(DecorationModule.class).getCurMaxDecorationInfo();
        req.setDecorationClass(result.decorationClass);
        req.setDecorationOverTime((int)(result.decorationOverTime));
        NewMonopolyMarketMgr.sendAppointActivityPacket(player.getUserId(), CrossProtocol.C_CROSS_NEW_MONOPOLY_MARKET_GET_USER_DATA, req);
    }

    /**
     * 同步玩家数据
     */
    public void synRoleData(){
        NewMonopolyMarketProto.NewMonopolyMarketUserRespMsg.Builder builder = NewMonopolyMarketProto.NewMonopolyMarketUserRespMsg.newBuilder();
        // 下发玩家数据
        NewMonopolyMarketProto.NewMonopolyMarketUserEntity.Builder userEntity = NewMonopolyMarketMgr.builderMonopolyMarketUserEntity(this);
        builder.setUserData(userEntity);
        // 当前正在派遣的对象
        for(Map.Entry<Integer, Map<Integer, Set<NewMonopolyMarketResGrabDispatchInfo>>> item : curDispatchInfoListMap.entrySet()){
            Map<Integer, Set<NewMonopolyMarketResGrabDispatchInfo>> map = item.getValue();
            for (Set<NewMonopolyMarketResGrabDispatchInfo> set : map.values()){
                for (NewMonopolyMarketResGrabDispatchInfo dispatchItem : set){
                    if(dispatchItem.getType() == eMonopolyMarketResType.RES_KING_NEW.getValue()){
                        builder.addPatronsDispatchInfo(NewMonopolyMarketMgr.builderMonopolyMarketResGrabDispatchTimesEntity(dispatchItem));
                    }else if (dispatchItem.getType() == eMonopolyMarketResType.RES_QUEEN_NEW.getValue()){
                        builder.addBeautyDispatchInfo(NewMonopolyMarketMgr.builderMonopolyMarketResGrabDispatchTimesEntity(dispatchItem));
                    }
                }
            }
        }
        player.sendPacket(YanQuMessageUtils.buildMessage(ClientProtocol.U_NEW_MONOPOLY_MARKET_USER_DATA, builder));
    }

    /**
     * 同步玩家基本数据到跨服
     */
    public void syncPlayerBaseInfoToCross(){
        if (NewMonopolyMarketMgr.canEnterSystem(player)) {
            if(userData.getOfficeCurPos() < 0){
                return;
            }
            NewMonopolyMarketProto.NewMonopolyMarketSynUserDataToCrossReqMsg.Builder builder = NewMonopolyMarketProto.NewMonopolyMarketSynUserDataToCrossReqMsg.newBuilder();
            UserInfo userInfo = UserMgr.getUserInfo(player.getUserId());
            if(userInfo.getDecoration() != null){
                builder.setDecoration(userInfo.getDecoration());
            }
            builder.setTitleId(userInfo.getTitleId());
            builder.setPrestige(userInfo.getPrestige().longValue());
            builder.setCurPos(userData.getOfficeCurPos());
            UserDecorationInfoResult result = player.getModule(DecorationModule.class).getCurMaxDecorationInfo();
            builder.setDecorationClass(result.decorationClass);
            builder.setDecorationOverTime((int)(result.decorationOverTime));
            NewMonopolyMarketMgr.sendAppointActivityPacket(player.getUserId(), CrossProtocol.C_CROSS_NEW_MONOPOLY_MARKET_SYN_USER_DATA_TO_CROSS, builder);
        }
    }

    /**
     * 发送配置
     */
    public void sendConfigToClient() {
        if (NewMonopolyMarketMgr.canEnterSystem(player)) {
            CrossSystemGroupMgr.sendAppointActivityPacket(player.getUserId(),
                    Protocol.C_CROSS_NEW_MONOPOLY_MARKET_SYNC_CONFIG,
                    eSystemId.NewMonopolyMarket.getValue(),
                    NewMonopolyMarketProto.NewMonopolyMarketBaseConfigSync.newBuilder());
        }
    }


    /**
     * 判断对象是否被派遣
     * @return
     */
    public boolean isDispatch(int type, int objectId){
        List<Set<NewMonopolyMarketResGrabDispatchInfo>> list = getCurDispatchInfoListMap(type);
        for (Set<NewMonopolyMarketResGrabDispatchInfo> item : list){
            for (NewMonopolyMarketResGrabDispatchInfo dispatchInfo : item){
                if(dispatchInfo.getDispatchId() == objectId){
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 添加派遣记录
     * @param resGroupId 资源分组id
     * @param posIndex 位置
     */
    public void addDispatchInfo(int resGroupId, int type, int posIndex, List<Integer> dispatchList,int time){
        Map<Integer, Set<NewMonopolyMarketResGrabDispatchInfo>>  map = getCurDispatchInfoListMap(resGroupId,true);

        Set<NewMonopolyMarketResGrabDispatchInfo> set = map.get(posIndex);
        if(set == null){
            set = new HashSet<>();
            map.put(posIndex,set);
        }
        for (int objectId : dispatchList){
            NewMonopolyMarketResGrabDispatchInfo dispatchInfo = new NewMonopolyMarketResGrabDispatchInfo();
            dispatchInfo.setResGroupId(resGroupId);
            dispatchInfo.setDispatchId(objectId);
            dispatchInfo.setPosIndex(posIndex);
            dispatchInfo.setType(type);
            dispatchInfo.setSeatTime(time);
            set.add(dispatchInfo);
        }
    }

    /**
     * 按资源分组类型 找派遣队伍
     * @param type
     * @return
     */
    public List<Set<NewMonopolyMarketResGrabDispatchInfo>> getCurDispatchInfoListMap(int type){
        List<Set<NewMonopolyMarketResGrabDispatchInfo>> list = new ArrayList<>();
        for (Map.Entry<Integer, Map<Integer, Set<NewMonopolyMarketResGrabDispatchInfo>>> mapEntry : curDispatchInfoListMap.entrySet()) {
            for (Map.Entry<Integer, Set<NewMonopolyMarketResGrabDispatchInfo>> entry : mapEntry.getValue().entrySet()) {
                for (NewMonopolyMarketResGrabDispatchInfo info : entry.getValue()) {
                    if(info.getType() == type){
                        list.add(entry.getValue());
                    }
                    break;
                }
            }
        }
        return list;
    }

    /**
     * 按资源分组id 找派遣队伍
     * @param resGroupId
     * @param newIfNull
     * @return
     */
    public Map<Integer, Set<NewMonopolyMarketResGrabDispatchInfo>> getCurDispatchInfoListMap(int resGroupId, boolean newIfNull){
        Map<Integer, Set<NewMonopolyMarketResGrabDispatchInfo>> map = curDispatchInfoListMap.get(resGroupId);
        if(map == null && newIfNull){
            map = new ConcurrentHashMap<>();
            curDispatchInfoListMap.put(resGroupId, map);
        }
        return map;
    }

    public Map<Integer, Map<Integer, Set<NewMonopolyMarketResGrabDispatchInfo>>> getCurDispatchInfoListMap() {
        return curDispatchInfoListMap;
    }

    /**
     * 榷署操作
     * @param type 0：入座；1：撤回
     */
    public int officeAction(int type, int posIndex, int seatTime, long seatUserId, NewMonopolyMarketProto.NewMonopolyMarketOfficeActionReqMsg req) {
        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }
        NewMonopolyMarketProto.NewMonopolyMarketOfficeActionCrossReqMsg.Builder toCrossMsg = NewMonopolyMarketProto.NewMonopolyMarketOfficeActionCrossReqMsg.newBuilder();
        if(type == 0){
            NewMonopolyMarketMgr.refreshUser(player,true,false);
            int ret = NewMonopolyMarketMgr.checkTodayDispatchTimes(eMonopolyMarketResType.OFFICE_NEW.getValue(), userData.getOfficeRobTimes());
            if(ret != 0){
                return ret;
            }
            // 判断元宝是否足够
            int needConsumeGold = NewMonopolyMarketMgr.calSitDownConsumeGold(userData);
            if(needConsumeGold > 0){
                Property property = new Property(GameConfig.GAME_MONEY_INGOTS, BigInteger.valueOf(needConsumeGold));
                if(!player.getModule(CurrencyModule.class).currencyIsEnough(property)){
                    return GameErrorCode.E_BAG_INGOTS_NO_ENOUGH;
                }
                // 预扣除
                player.getModule(PreReduceModule.class).preReduce(property);
                toCrossMsg.setConsume(PropertyHelper.parsePropertyToString(property));
            }
            //战斗数据
            UserDecorationInfoResult result = player.getModule(DecorationModule.class).getCurMaxDecorationInfo();
            toCrossMsg.setDecorationClass(result.decorationClass);
            toCrossMsg.setDecorationOverTime((int)(result.decorationOverTime));
            toCrossMsg.setPlayerInfo(PlayerBasePb.parsePlayerBaseTempMsg(UserMgr.getUserBaseInfo(player.getUserId(), GameServer.getInstance().getServerId())));
        }

        toCrossMsg.setCtsMsg(req);
        NewMonopolyMarketMgr.sendAppointActivityPacket(player.getUserId(), CrossProtocol.C_CROSS_NEW_MONOPOLY_MARKET_OFFICE_ACTION, toCrossMsg);
        return 0;
    }

    public int searchFromCross(int guanYin, NewMonopolyMarketProto.NewMonopolyMarketResGrabSearchPointEntity pointList) {
        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }
        if(userData.getGuanYin() < guanYin){
            return GameErrorCode.E_NEW_MONOPOLY_MARKET_NO_PHYSICAL;
        }
        long oldValue = userData.getGuanYin();
        userData.setGuanYin(userData.getGuanYin() - guanYin);
        NewMonopolyMarketTempPoint tempPoint = new NewMonopolyMarketTempPoint();
        tempPoint.setPosIndex(pointList.getPosIndex());
        tempPoint.setResGroupId(pointList.getResGroupId());
        userData.getSearchPointMap().put(pointList.getResGroupId(), tempPoint);
        userData.setUpdateOption();

        AutoLogMgr.add(new NewMonopolyMarketUserPhysicalChangeLogData(getUserId(), userData.getWeekId(), userData.getOfficeCurPos(), userData.getOfficeLevel(),
                userData.getOfficeNo(), 1, oldValue, userData.getGuanYin()));

        NewMonopolyMarketProto.NewMonopolyMarketResGrabSearchRespMsg.Builder respMsg = NewMonopolyMarketProto.NewMonopolyMarketResGrabSearchRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.addPointList(pointList);
        player.sendPacket(Protocol.U_NEW_MONOPOLY_MARKET_RES_GRAB_SEARCH, respMsg);
        synRoleData();
        return 0;
    }

    public int changeTeam(int action, int resGroupId, int posIndex) {
        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }
        NewMonopolyMarketTempPoint waitDispatchPoint = userData.getWaitDispatchPoint();
        if(waitDispatchPoint == null){
            return GameErrorCode.E_NEW_MONOPOLY_MARKET_WAIT_CHANGE_TEAM_INFO_EMPTY;
        }
        if(DateHelper.getCurrentSecond() > waitDispatchPoint.getTime()){
            userData.setWaitDispatchPoint(null);
            return GameErrorCode.E_NEW_MONOPOLY_MARKET_WAIT_CHANGE_TEAM_INFO_TIMEOUT;
        }

        if(action == 0) {
            userData.setWaitDispatchPoint(null);
        }

        //判断撤回的队伍是否存在
        if(action == 1){

        }

        NewMonopolyMarketProto.NewMonopolyMarketCrossResGrabChangeTeamConfirmReqMsg.Builder crossReq =
                NewMonopolyMarketProto.NewMonopolyMarketCrossResGrabChangeTeamConfirmReqMsg.newBuilder();
        crossReq.setAction(action);
        crossReq.setResGroupId(resGroupId);
        crossReq.setPosIndex(posIndex);
        crossReq.setTargetResGroupId(waitDispatchPoint.getResGroupId());
        crossReq.setTargetPosIndex(waitDispatchPoint.getPosIndex());

        NewMonopolyMarketMgr.sendAppointActivityPacket(player.getUserId(),
                Protocol.C_NEW_MONOPOLY_MARKET_CHANGE_TEAM_CONFIRM, crossReq);

        return 0;
    }

    public int getInSystemId() {
        return inSystemId;
    }

    public void changeInSystemId(int systemId){
        if(systemId > 0){
            inSystemTime = DateHelper.getCurrentSecond();
        }
        if(systemId == 0){
            if(this.inSystemId > 0 && this.inSystemTime > 0){
                userData.setActiveTime(userData.getActiveTime() + (DateHelper.getCurrentSecond() - this.inSystemTime));
                this.inSystemTime = 0;
            }
        }
        if(systemId == -1){
            this.inSystemTime = 0;
        }
        this.inSystemId = systemId;
    }
}
